New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(core): allow users to define timing of ViewChild/ContentChild queries #28810
Conversation
5e9ad62
to
2c25c7a
Compare
…eries Prior to this commit, the timing of `ViewChild`/`ContentChild` query resolution depended on the results of each query. If any results for a particular query were nested inside embedded views (e.g. *ngIfs), that query would be resolved after change detection ran. Otherwise, the query would be resolved as soon as nodes were created. This inconsistency in resolution timing had the potential to cause confusion because query results would sometimes be available in ngOnInit, but sometimes wouldn't be available until ngAfterContentInit or ngAfterViewInit. Code depending on a query result could suddenly stop working as soon as an *ngIf or an *ngFor was added to the template. With this commit, users can dictate when they want a particular `ViewChild` or `ContentChild` query to be resolved with the `static` flag. For example, one can mark a particular query as `static: false` to ensure change detection always runs before its results are set: ```ts @ContentChild('foo', {static: false}) foo !: ElementRef; ``` This means that even if there isn't a query result wrapped in an *ngIf or an *ngFor now, adding one to the template later won't change the timing of the query resolution and potentially break your component. Similarly, if you know that your query needs to be resolved earlier (e.g. you need results in an ngOnInit hook), you can mark it as `static: true`. ```ts @ViewChild(TemplateRef, {static: true}) foo !: TemplateRef; ``` Note: this means that your component will not support *ngIf results. If you do not supply a `static` option when creating your `ViewChild` or `ContentChild` query, the default query resolution timing will kick in. Note: This new option only applies to `ViewChild` and `ContentChild` queries, not `ViewChildren` or `ContentChildren` queries, as those types already resolve after CD runs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm but please document the default.
merge-assistance: global approval from igor/misko |
Introduces an update schematic for the "@angular/core" package that automatically migrates pre-V8 "ViewChild" and "ContentChild" queries to the new explicit timing syntax. This is not required yet, but with Ivy, queries will be "dynamic" by default. Therefore specifying an explicit query timing ensures that developers can smoothly migrate to Ivy (once it's the default). Read more about the explicit timing API here: angular#28810
Introduces an update schematic for the "@angular/core" package that automatically migrates pre-V8 "ViewChild" and "ContentChild" queries to the new explicit timing syntax. This is not required yet, but with Ivy, queries will be "dynamic" by default. Therefore specifying an explicit query timing ensures that developers can smoothly migrate to Ivy (once it's the default). Read more about the explicit timing API here: angular#28810
Introduces an update schematic for the "@angular/core" package that automatically migrates pre-V8 "ViewChild" and "ContentChild" queries to the new explicit timing syntax. This is not required yet, but with Ivy, queries will be "dynamic" by default. Therefore specifying an explicit query timing ensures that developers can smoothly migrate to Ivy (once it's the default). Read more about the explicit timing API here: angular#28810
Introduces an update schematic for the "@angular/core" package that automatically migrates pre-V8 "ViewChild" and "ContentChild" queries to the new explicit timing syntax. This is not required yet, but with Ivy, queries will be "dynamic" by default. Therefore specifying an explicit query timing ensures that developers can smoothly migrate to Ivy (once it's the default). Read more about the explicit timing API here: angular#28810
Introduces an update schematic for the "@angular/core" package that automatically migrates pre-V8 "ViewChild" and "ContentChild" queries to the new explicit timing syntax. This is not required yet, but with Ivy, queries will be "dynamic" by default. Therefore specifying an explicit query timing ensures that developers can smoothly migrate to Ivy (once it's the default). Read more about the explicit timing API here: angular#28810
Introduces an update schematic for the "@angular/core" package that automatically migrates pre-V8 "ViewChild" and "ContentChild" queries to the new explicit timing syntax. This is not required yet, but with Ivy, queries will be "dynamic" by default. Therefore specifying an explicit query timing ensures that developers can smoothly migrate to Ivy (once it's the default). Read more about the explicit timing API here: angular#28810
Introduces an update schematic for the "@angular/core" package that automatically migrates pre-V8 "ViewChild" and "ContentChild" queries to the new explicit timing syntax. This is not required yet, but with Ivy, queries will be "dynamic" by default. Therefore specifying an explicit query timing ensures that developers can smoothly migrate to Ivy (once it's the default). Read more about the explicit timing API here: angular#28810
Introduces an update schematic for the "@angular/core" package that automatically migrates pre-V8 "ViewChild" and "ContentChild" queries to the new explicit timing syntax. This is not required yet, but with Ivy, queries will be "dynamic" by default. Therefore specifying an explicit query timing ensures that developers can smoothly migrate to Ivy (once it's the default). Read more about the explicit timing API here: angular#28810
) Introduces an update schematic for the "@angular/core" package that automatically migrates pre-V8 "ViewChild" and "ContentChild" queries to the new explicit timing syntax. This is not required yet, but with Ivy, queries will be "dynamic" by default. Therefore specifying an explicit query timing ensures that developers can smoothly migrate to Ivy (once it's the default). Read more about the explicit timing API here: #28810 PR Close #28983
Seems to me that if they had chosen a default behavior, it might have broken some people's expected behavior. Which could be hard to debug. |
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
Prior to this commit, the timing of
ViewChild
/ContentChild
queryresolution depended on the results of each query. If any results
for a particular query were nested inside embedded views (e.g.
*ngIfs), that query would be resolved after change detection ran.
Otherwise, the query would be resolved as soon as nodes were created.
This inconsistency in resolution timing had the potential to cause
confusion because query results would sometimes be available in
ngOnInit, but sometimes wouldn't be available until ngAfterContentInit
or ngAfterViewInit. Code depending on a query result could suddenly
stop working as soon as an *ngIf or an *ngFor was added to the template.
With this commit, users can dictate when they want a particular
ViewChild
orContentChild
query to be resolved with thestatic
flag.For example, one can mark a particular query as
static: false
toensure change detection always runs before its results are set:
This means that even if there isn't a query result wrapped in an
*ngIf or an *ngFor now, adding one to the template later won't change
the timing of the query resolution and potentially break your component.
Similarly, if you know that your query needs to be resolved earlier
(e.g. you need results in an ngOnInit hook), you can mark it as
static: true
.Note: this means that your component will not support *ngIf results.
If you do not supply a
static
option when creating yourViewChild
orContentChild
query, the default query resolution timing will kick in.Note: This new option only applies to
ViewChild
andContentChild
queries,not
ViewChildren
orContentChildren
queries, as those types alreadyresolve after CD runs.